#ifndef THREADPOOL_H
#define THREADPOOL_H

#include<pthread.h>
#include<list>
#include"locker.h"
#include<iostream>
using namespace std;

//线程池类，定义代码类复用代码
//T为任务类
template<class T>
class threadpool{
public:
    threadpool(int thread_num=8,int max_requests=10000);
    ~threadpool();
    //添加任务到请求队列
    bool  append(T* request);

private:
    static void* worker(void* arg);
    void run();   //取出任务执行


private:
    //线程的数量
    int m_thread_number;  

    //线程池数组
    pthread_t* m_threads;

    //请求队列容量
    int m_max_requests;

    //请求队列
    list<T*> m_workqueue;

    //互斥锁,只负责对请求队列加锁或解锁
    locker m_queuelocker;

    //信号量，请求队列通知,判断是否有任务需要处理
    sem m_queuestat;

    //是否结束线程
    bool m_semstop;

 

};

template<class T>
threadpool<T>::threadpool(int thread_num,int max_requests){
    this->m_thread_number = thread_num;
    this->m_max_requests = max_requests;
    this->m_semstop = false;
    this->m_threads = NULL;

    if (thread_num<=0||max_requests<=0||thread_num>max_requests){
        throw exception();
    }
    this->m_threads = new pthread_t[this->m_thread_number];  //注意析构
    if(!this->m_threads){
        throw exception();
    }

    //创建thread_number个线程,设置线程分离
    for(int i = 0;i<this->m_thread_number;++i){
        cout<<"Create the "<<i<<"th thread"<<endl;
        if(pthread_create(m_threads+i,NULL,worker,this)!=0){
            delete [] m_threads;
            throw exception();
        }
        //创建成功了，设置线程分离
        if(pthread_detach(*(this->m_threads+i))!=0){
            delete [] m_threads;
            throw exception();
        }
    }
}

template<class T>
threadpool<T>::~threadpool(){
    delete []m_threads;
    m_semstop = true;
}


template<class T>
bool threadpool<T>::append(T* request){
    //请求队列是一个公共资源，要上锁
    this->m_queuelocker.lock();
    if(m_workqueue.size()>m_max_requests){
        this->m_queuelocker.unlock();
        return false;
    }
    this->m_workqueue.push_back(request);
    this->m_queuelocker.unlock();
    this->m_queuestat.post(); //请求队列中的内容加1
    return true;
}

template<class T>
void* threadpool<T>::worker(void* arg){
    //不能访问非静态成员
    threadpool* pool  = (threadpool*) arg;
    pool->run();
    return pool;
}

//从请求对列中获取一个任务出来执行
template<class T>
void threadpool<T>::run(){
    while(!this->m_semstop){
        this->m_queuestat.wait();
        this->m_queuelocker.lock();
        T* request = this->m_workqueue.front();
        this->m_workqueue.pop_front();
        this->m_queuelocker.unlock();
        if(!request){
            continue;
        }
        request->process(); //任务区执行相应的处理代码
    }
}

  
#endif